package com.audaque.springboot.foshanupload.jwtcore.util.encode.rsaPem;

import java.util.Objects;

/**
 * RsaPem测试控制台主程序
 * <p>
 * GitHub:https://github.com/xiangyuecn/RSA-java
 */

public class Test {


    public static void test1(String pem_pkcs1_prv) throws Exception {
        RsaUtil rsa = new RsaUtil(RsaPem.FromPEM(pem_pkcs1_prv));
        RsaPem pem = rsa.ToPEM(false);
        String pem_pkcs1_prv_copy = pem.ToPEM_PKCS1(false);
        String pem_pkcs1_pub = pem.ToPEM_PKCS1(true);
        if (!Objects.equals(pem_pkcs1_prv, pem_pkcs1_prv_copy)) {
            throw new Exception("私钥反向生成秘钥对不正确");
        }
        String str = "abc内容123";
        System.out.println("str:" + str);
        String en = rsa.Encode(str);
        System.out.println("en:" + en);
        String de = rsa.Decode(en);
        System.out.println("de:" + de);
        if (!de.equals(str)) {
            throw new Exception("解密失败");
        }

    }

    public static void test2() throws Exception {
        //RS256:1024
        //RS512:2048
        RsaUtil rsa = new RsaUtil(2048);
        RsaPem pem = rsa.ToPEM(false);
        String pem_pkcs1_prv = pem.ToPEM_PKCS1(false);
        System.out.println("pem_pkcs1_prv:" + pem_pkcs1_prv);
        String pem_pkcs1_pub = pem.ToPEM_PKCS1(true);
        System.out.println("pem_pkcs1_pub:" + pem_pkcs1_pub);
        String pem_pkcs8_prv = pem.ToPEM_PKCS8(false);
        System.out.println("pem_pkcs8_prv:" + pem_pkcs8_prv);
        String pem_pkcs8_pub = pem.ToPEM_PKCS8(true);
        System.out.println("pem_pkcs8_pub:" + pem_pkcs8_pub);
        System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        String str = "abc内容123";
        System.out.println("str:" + str);
        String en = rsa.Encode(str);
        System.out.println("en:" + en);
        String de = rsa.Decode(en);
        System.out.println("de:" + de);
        if (!de.equals(str)) {
            throw new Exception("解密失败");
        }

    }

    public static void test8(String pem_pkcs8_prv) throws Exception {
        RsaUtil rsa = new RsaUtil(RsaPem.FromPEM(pem_pkcs8_prv));
        RsaPem pem = rsa.ToPEM(false);
        String pem_pkcs8_prv_copy = pem.ToPEM_PKCS8(false);
        String pem_pkcs8_pub = pem.ToPEM_PKCS8(true);
        if (!Objects.equals(pem_pkcs8_prv, pem_pkcs8_prv_copy)) {
            throw new Exception("私钥反向生成秘钥对不正确");
        }
        String str = "abc内容123";
        System.out.println("str:" + str);
        String en = rsa.Encode(str);
        System.out.println("en:" + en);
        String de = rsa.Decode(en);
        System.out.println("de:" + de);
        if (!de.equals(str)) {
            throw new Exception("解密失败");
        }

    }


    static void RSATest(boolean fast) throws Exception {
        //新生成一个RSA密钥，也可以通过已有的pem、xml文本密钥来创建RSA
        //RS256:1024
        //RS512:2048
        RsaUtil rsa = new RsaUtil(2048);
        //RsaUtil rsa = new RsaUtil("pem或xml文本密钥");
        //RsaUtil rsa = new RsaUtil(RsaPem.FromPEM("pem文本密钥"));
        //RsaUtil rsa = new RsaUtil(RsaPem.FromXML("xml文本密钥"));

        //得到pem对象
        RsaPem pem = rsa.ToPEM(false);
        //提取密钥pem字符串
        String pem_pkcs1 = pem.ToPEM_PKCS1(false);
        String pem_pkcs8 = pem.ToPEM_PKCS8(false);
        //提取密钥xml字符串
        String xml = rsa.ToXML(false);

        System.out.println("【" + rsa.keySize() + "私钥（XML）】：");
        System.out.println(xml);
        System.out.println();
        System.out.println("【" + rsa.keySize() + "私钥（PKCS#1）】：");
        System.out.println(pem_pkcs1);
        System.out.println();
        System.out.println("【" + rsa.keySize() + "公钥（PKCS#8）】：");
        System.out.println(pem.ToPEM_PKCS8(true));
        System.out.println();


        String str = "abc内容123";
        String en = rsa.Encode(str);
        System.out.println("【加密】：");
        System.out.println(en);

        System.out.println("【解密】：");
        String de = rsa.Decode(en);
        AssertMsg(de, de.equals(str));

        if (!fast) {
            String str2 = str;
            for (int i = 0; i < 15; i++) str2 += str2;
            System.out.println("【长文本加密解密】：");
            AssertMsg(str2.length() + "个字 OK", rsa.Decode(rsa.Encode(str2)).equals(str2));
        }


        System.out.println("【签名SHA1】：");
        String sign = rsa.Sign("SHA1", str);
        System.out.println(sign);
        AssertMsg("校验 OK", rsa.Verify("SHA1", sign, str));
        System.out.println();


        //用pem文本创建RSA
        RsaUtil rsa2 = new RsaUtil(RsaPem.FromPEM(pem_pkcs8));
        RsaPem pem2 = rsa2.ToPEM(false);
        System.out.println("【用PEM新创建的RSA是否和上面的一致】：");
        Assert("XML：", pem2.ToXML(false).equals(pem.ToXML(false)));
        Assert("PKCS1：", pem2.ToPEM_PKCS1(false).equals(pem.ToPEM_PKCS1(false)));
        Assert("PKCS8：", pem2.ToPEM_PKCS8(false).equals(pem.ToPEM_PKCS8(false)));

        //用xml文本创建RSA
        RsaUtil rsa3 = new RsaUtil(RsaPem.FromXML(xml));
        RsaPem pem3 = rsa3.ToPEM(false);
        System.out.println("【用XML新创建的RSA是否和上面的一致】：");
        Assert("XML：", pem3.ToXML(false).equals(pem.ToXML(false)));
        Assert("PKCS1：", pem3.ToPEM_PKCS1(false).equals(pem.ToPEM_PKCS1(false)));
        Assert("PKCS8：", pem3.ToPEM_PKCS8(false).equals(pem.ToPEM_PKCS8(false)));


        //--------RsaPem私钥验证---------
        //使用PEM全量参数构造pem对象
        RsaPem pemX = new RsaPem(pem.Key_Modulus, pem.Key_Exponent, pem.Key_D
                , pem.Val_P, pem.Val_Q, pem.Val_DP, pem.Val_DQ, pem.Val_InverseQ);
        System.out.println("【RsaPem是否和原始RSA一致】：");
        System.out.println(pemX.keySize() + "位");
        Assert("XML：", pemX.ToXML(false).equals(pem.ToXML(false)));
        Assert("PKCS1：", pemX.ToPEM_PKCS1(false).equals(pem.ToPEM_PKCS1(false)));
        Assert("PKCS8：", pemX.ToPEM_PKCS8(false).equals(pem.ToPEM_PKCS8(false)));
        System.out.println("仅公钥：");
        Assert("XML：", pemX.ToXML(true).equals(pem.ToXML(true)));
        Assert("PKCS1：", pemX.ToPEM_PKCS1(true).equals(pem.ToPEM_PKCS1(true)));
        Assert("PKCS8：", pemX.ToPEM_PKCS8(true).equals(pem.ToPEM_PKCS8(true)));

        //--------RsaPem公钥验证---------
        RsaPem pemY = new RsaPem(pem.Key_Modulus, pem.Key_Exponent, null);
        System.out.println("【RsaPem仅公钥是否和原始RSA一致】：");
        System.out.println(pemY.keySize() + "位");
        Assert("XML：", pemY.ToXML(false).equals(pem.ToXML(true)));
        Assert("PKCS1：", pemY.ToPEM_PKCS1(false).equals(pem.ToPEM_PKCS1(true)));
        Assert("PKCS8：", pemY.ToPEM_PKCS8(false).equals(pem.ToPEM_PKCS8(true)));


        if (!fast) {
            //使用n、e、d构造pem对象
            RsaPem pem4 = new RsaPem(pem.Key_Modulus, pem.Key_Exponent, pem.Key_D);
            RsaUtil rsa4 = new RsaUtil(pem4);
            System.out.println("【用n、e、d构造解密】");
            de = rsa4.Decode(en);
            AssertMsg(de, de.equals(str));
        }


        System.out.println();
        System.out.println();
        System.out.println("【" + pem.keySize() + "私钥（PKCS#8）】：");
        System.out.println(pem.ToPEM_PKCS8(false));
        System.out.println();
        System.out.println("【" + pem.keySize() + "公钥（PKCS#1）】：不常见的公钥格式");
        System.out.println(pem.ToPEM_PKCS1(true));
    }


    static void Assert(String msg, boolean check) throws Exception {
        AssertMsg(msg + check, check);
    }

    static void AssertMsg(String msg, boolean check) throws Exception {
        if (!check) throw new Exception(msg);
        System.out.println(msg);
    }

    public static void main(String[] argv) throws Exception {

        System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        test2();
        System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

        test1("-----BEGIN RSA PRIVATE KEY-----\n" +
                "MIIEpQIBAAKCAQEAwQ1XxFJ9UdLz0mCrGDzYqvwDELIE9GXtwKAwaOOCPXDutMth\n" +
                "ILW/ExeJCbweU63J4hgNb/lwrtY86mbRxzR1xY6dkVcJV6hj/aGvEeKl1fdaKN4q\n" +
                "Lhc6JjRckeQ7SFWaNzn4EoU6rnTSwqrL/yIKU7Irbb6SoLZ34XCNUVe3dgpK6VUK\n" +
                "juiyPf7YZZsLWeviOq9n2lRf7Nn/oRQLRJ7GWrz6IXeHKF9pj6dskUqnmk361sXJ\n" +
                "dMX/BpD25odTLEuSSJrpQ+QjcyoIu7npEDWSjKv7KAvLLnyr7KZ304TgEGdo9nFU\n" +
                "UmcduXX2/KWPkPAP8qUhWWI09O9CJJsUoKbu8wIDAQABAoIBAQCK/uJcVdApI6ut\n" +
                "ozBNCTIvGbfTQ3lRxjnCYRO50WSqfC9CONS7yl/CjUV7nthvA0fB4/N41a4OE+5U\n" +
                "Dqent9u73A0S4gm19WXY7ZqxU/B299sQZbUU7mBNtZGY8SzFzex1KuWz3/z6Mt60\n" +
                "jmjGT2oEDNo77+R+liIGTRVSpcdP0qUuoWCLyXVlSVxWt8foeAOlFm+GetsSyMmh\n" +
                "Lg/FSPPm/U10u+vD47ufTbhesZBHIQnQw7MhvzWGeEeDptGVFQ/xdV+xobEAVrPy\n" +
                "YoLCbIif7SYITifm2B22g3HUV2uVL9IFyXUxVoOblnzBxj/G3IIGEkTqxwLNVZXS\n" +
                "2XzxEoyxAoGBANyqcisFFIdA8z8iWmq0ycuIDZ+CwaUVaQYEt66xzEbtHN5RhLnt\n" +
                "Yb89uiVPQl4AdAZQf9HLiODSBDSp/zWHrg31pdmfNdYt0FMdTdf03+/qXtv+0JiP\n" +
                "9VdtLZCMGNZLFUNj1lmHELz3ofkRJXYxJ/ZqVmXEOYjGwX7yjYDTgq+lAoGBAN/2\n" +
                "9D0egTVFVtmjq8C6qUxevrUIpK3mDtQUFr0PsBsEMZeTLVwtoux7WPONt1jXqRmt\n" +
                "pGbDoDBIxAV07oSNJxOBujYt7zUHw3r0RSv6lIUmc+9QArJ3o8REcDXOdndQ3+pG\n" +
                "nvTgWI3Gqr8gKgMlXCySfqeiKItuYU7Jf+l8b+C3AoGAPxd0wRwYvHszkU+PLoc2\n" +
                "Uz05N+w41ayDdLcQlaA8WeMdp+sC2e4nTnilqlk5DotuoQePJDrfjfg+P5iDYZjD\n" +
                "iTY9DzXYPL6om7r7MM3Q4VXPfXMjzRsL+M08g+GqkEqzb6sx9DML9BuRchcW8O4p\n" +
                "EOlifoJWOOcrF9Ld5oGTEgkCgYEAiqnbjfvVA6Zqn1U2gZ0QNLh0WqF/VCucArJt\n" +
                "YaDU5+UwzyfQbcHTnZbA/ApB+j+L8toPb5CvHTXwJ3C+PFMoXmtzXxgRgkPMQ9P4\n" +
                "/8GlMssb/I8NHHH2cw3sa2Po9Padq+8Ne49rRFw8WxkO6eO3reEFicRcVfeBR8Z5\n" +
                "65WfrwECgYEAl/bVPi5hOjIX+o3ZL2UJb1+OPg5vgW1K5nLXz78avH7xpr/JQJrl\n" +
                "xVNc4h9fEhTaWKMAAKpoowAuPzmy2/k1jXCEoO97M5VEYkP+Q816LlrX+iDXlgwO\n" +
                "12LK2I5rDROD5O/WKezPY3bItNCoMM69HOkg49mApOj824zkuEQV82M=\n" +
                "-----END RSA PRIVATE KEY-----");
        System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

        test8("-----BEGIN PRIVATE KEY-----\n" +
                "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDBDVfEUn1R0vPS\n" +
                "YKsYPNiq/AMQsgT0Ze3AoDBo44I9cO60y2Egtb8TF4kJvB5TrcniGA1v+XCu1jzq\n" +
                "ZtHHNHXFjp2RVwlXqGP9oa8R4qXV91oo3iouFzomNFyR5DtIVZo3OfgShTqudNLC\n" +
                "qsv/IgpTsittvpKgtnfhcI1RV7d2CkrpVQqO6LI9/thlmwtZ6+I6r2faVF/s2f+h\n" +
                "FAtEnsZavPohd4coX2mPp2yRSqeaTfrWxcl0xf8GkPbmh1MsS5JImulD5CNzKgi7\n" +
                "uekQNZKMq/soC8sufKvspnfThOAQZ2j2cVRSZx25dfb8pY+Q8A/ypSFZYjT070Ik\n" +
                "mxSgpu7zAgMBAAECggEBAIr+4lxV0Ckjq62jME0JMi8Zt9NDeVHGOcJhE7nRZKp8\n" +
                "L0I41LvKX8KNRXue2G8DR8Hj83jVrg4T7lQOp6e327vcDRLiCbX1ZdjtmrFT8Hb3\n" +
                "2xBltRTuYE21kZjxLMXN7HUq5bPf/Poy3rSOaMZPagQM2jvv5H6WIgZNFVKlx0/S\n" +
                "pS6hYIvJdWVJXFa3x+h4A6UWb4Z62xLIyaEuD8VI8+b9TXS768Pju59NuF6xkEch\n" +
                "CdDDsyG/NYZ4R4Om0ZUVD/F1X7GhsQBWs/JigsJsiJ/tJghOJ+bYHbaDcdRXa5Uv\n" +
                "0gXJdTFWg5uWfMHGP8bcggYSROrHAs1VldLZfPESjLECgYEA3KpyKwUUh0DzPyJa\n" +
                "arTJy4gNn4LBpRVpBgS3rrHMRu0c3lGEue1hvz26JU9CXgB0BlB/0cuI4NIENKn/\n" +
                "NYeuDfWl2Z811i3QUx1N1/Tf7+pe2/7QmI/1V20tkIwY1ksVQ2PWWYcQvPeh+REl\n" +
                "djEn9mpWZcQ5iMbBfvKNgNOCr6UCgYEA3/b0PR6BNUVW2aOrwLqpTF6+tQikreYO\n" +
                "1BQWvQ+wGwQxl5MtXC2i7HtY8423WNepGa2kZsOgMEjEBXTuhI0nE4G6Ni3vNQfD\n" +
                "evRFK/qUhSZz71ACsnejxERwNc52d1Df6kae9OBYjcaqvyAqAyVcLJJ+p6Ioi25h\n" +
                "Tsl/6Xxv4LcCgYA/F3TBHBi8ezORT48uhzZTPTk37DjVrIN0txCVoDxZ4x2n6wLZ\n" +
                "7idOeKWqWTkOi26hB48kOt+N+D4/mINhmMOJNj0PNdg8vqibuvswzdDhVc99cyPN\n" +
                "Gwv4zTyD4aqQSrNvqzH0Mwv0G5FyFxbw7ikQ6WJ+glY45ysX0t3mgZMSCQKBgQCK\n" +
                "qduN+9UDpmqfVTaBnRA0uHRaoX9UK5wCsm1hoNTn5TDPJ9BtwdOdlsD8CkH6P4vy\n" +
                "2g9vkK8dNfAncL48Uyhea3NfGBGCQ8xD0/j/waUyyxv8jw0ccfZzDexrY+j09p2r\n" +
                "7w17j2tEXDxbGQ7p47et4QWJxFxV94FHxnnrlZ+vAQKBgQCX9tU+LmE6Mhf6jdkv\n" +
                "ZQlvX44+Dm+BbUrmctfPvxq8fvGmv8lAmuXFU1ziH18SFNpYowAAqmijAC4/ObLb\n" +
                "+TWNcISg73szlURiQ/5DzXouWtf6INeWDA7XYsrYjmsNE4Pk79Yp7M9jdsi00Kgw\n" +
                "zr0c6SDj2YCk6PzbjOS4RBXzYw==\n" +
                "-----END PRIVATE KEY-----");
    }
}
